#pragma once
#ifndef _MYSTACK_H
#define _MYSTACK_H

template <typename T>
class MyStack {
private:
	T* ptr;
	int capacity;
	int cur;
	void resize(T* in, const int new_len);
public:
	MyStack(const int cap = 5);
	~MyStack();
	const T& top() const;
	void push(const T& item);
	void pop();
	bool empty();
	void showCapacity();
	void showCur();
};

template <typename T>
MyStack<T>::MyStack(const int cap = 5) :capacity(cap) {
	if (cap < 1) {
		throw "the capacity of stack less than 1";
	}
	ptr = new T[cap];
	cur = -1;
}

template <typename T>
MyStack<T>::~MyStack() {
	delete[] ptr;
}

template <typename T>
void MyStack<T>::resize(T* in, const int new_len) {
	if (new_len<=capacity) {
		throw "The new_len should be more than old_len when resize the stack ";
	}
	T* new_ptr = new T[new_len];
	for (int i = 0; i < capacity; i++) {
		new_ptr[i] = in[i];
	}
	delete[] in;
	in = new_ptr;
	capacity = new_len;
}

template <typename T>
const T& MyStack<T>::top() const {
	if (cur < 0) {
		throw "The stack is empty!";
	}
	return ptr[cur];
}

template <typename T>
void MyStack<T>::push(const T& item) {
	if (cur >= capacity-1) {
		resize(ptr, 2 * capacity);
	}
	ptr[++cur] = item;
}

template <typename T>
void MyStack<T>::pop() {
	if (cur < 0) {
		throw "The stack has been empty!";
	}
	cur--;
}

template <typename T>
bool MyStack<T>::empty() {
	return cur >= 0 ? false : true;
}

template <typename T>
void MyStack<T>::showCapacity() {
	cout << "The capacity of stack is:" << capacity << endl;
}

template <typename T>
void MyStack<T>::showCur() {
	cout << "The current pos of head of stack is: " << cur << endl;
}
#endif